<!--
 * @Author: 刘翔
 * @Date: 2025-08-19 10:41:39
 * @LastEditTime: 2025-09-01 16:39:29
 * @LastEditors: your name
 * @Description: DRG数据分析表格组件
 * @FilePath: \建达文件\ts-demo\ts-demo\src\pptHome\components\DataTableVertical.vue
-->
<template>
  <div class="data-table-vertical">
    <!-- 表格头部 -->
    <!-- 合并表格 -->
    <div class="merged-table">
      <table class="data-table">
        <thead>
          <tr>
            <!-- 基本信息列标题 -->
            <th v-for="column in columns.columns1" :key="column.prop" class="basic-info-header" :style="{ width: column.widthPercent + '%', fontSize: column.headerFontSize + 'px' }">
              {{ column.label }}
            </th>
            <!-- 详细数据列标题 -->
            <th v-for="column in columns.columns2" :key="column.prop" class="detail-data-header" :style="{ width: column.widthPercent + '%', fontSize: column.headerFontSize + 'px' }">
              {{ column.label }}
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(row, index) in tableData.data" :key="index">
            <!-- 基本信息列 - 只在第一行显示，其他行合并 -->
            <template v-if="index === 0">
              <td
                v-for="column in columns.columns1"
                :key="column.prop"
                :rowspan="tableData.data.length"
                class="basic-info-cell"
                :style="{ width: column.widthPercent + '%', fontSize: column.contentFontSize + 'px' }"
              >
                {{ tableData[column.prop] }}
              </td>
            </template>
            <!-- 详细数据列 -->
            <td
              v-for="column in columns.columns2"
              :key="column.prop"
              :class="getCellClass(row, column.prop)"
              class="detail-data-cell"
              :style="{ width: column.widthPercent + '%', fontSize: column.contentFontSize + 'px' }"
            >
              {{ formatCellValue(row[column.prop]) }}
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DataTableVertical',
  props: {
    // 表头背景色
    headerBgColor: {
      type: String,
      default: '#4874cb',
    },
    // PPT导出配置
    pptOptions: {
      type: Object,
      default: () => ({
        x: 0.4, // X轴位置
        y: 0.4, // Y轴位置

        title: {
          // 标题配置
          x: 0.5,
          y: 0.5,
          fontSize: 24,
          color: '363636',
          bold: true,
        },
        table: {
          // 表格配置
          colW: [], // 列宽数组，为空时自动计算
          rowH: 0.2, // 单行高度
          // 表格内容配置
          content: {
            fontSize: 8,
            color: '000000',
            bold: true,
          },
          // 表格标题配置
          title: {
            fontSize: 8,
            color: 'ffffff',
          },
          // 表格边框样式
          borderStyle: {
            color: '000000',
          },
          // 表格垂直对齐方式(middle, top, bottom)
          valign: 'middle',
          // 表格水平对齐方式(left, center, right)
          align: 'center',
          // 自动分页
          autoPage: true,
          // 自动分页标题是否显示
          autoPageRepeatHeader: true,
          // 自动分页标题行数
          autoPageHeaderRows: 1, // 单表头只需要1行
        },
      }),
    },
    tableData: {
      type: Object,
      default: () => ({
        DRG分组: 'ES23',
        DRG分组名称: '呼吸系统感染/炎症，伴一般并发症与合并症',
        RW: 0.6,
        data_list: [
          {
            低倍率病例占比: 4.32,
            低倍率病例占比是否标红: false,
            出院科室名称: '呼吸内科',
            平均住院天数: 10.18,
            '平均超支结余(元)': -209.37,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 5449.93,
            次均费用是否标红: false,
            病例数: 324,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -6.78,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 11.11,
            低倍率病例占比是否标红: true,
            出院科室名称: '内分泌科',
            平均住院天数: 9.5,
            '平均超支结余(元)': -296.74,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 5061.68,
            次均费用是否标红: false,
            病例数: 18,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -0.53,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 10,
            低倍率病例占比是否标红: false,
            出院科室名称: '心血管内科',
            平均住院天数: 9.9,
            '平均超支结余(元)': -1119.9,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 6624.41,
            次均费用是否标红: true,
            病例数: 10,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -1.12,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 0,
            低倍率病例占比是否标红: false,
            出院科室名称: '老年医学科',
            平均住院天数: 11.75,
            '平均超支结余(元)': -607.26,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 6391.21,
            次均费用是否标红: true,
            病例数: 8,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -0.49,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 0,
            低倍率病例占比是否标红: false,
            出院科室名称: '老年病科二',
            平均住院天数: 11.6,
            '平均超支结余(元)': -913.13,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 6155.79,
            次均费用是否标红: true,
            病例数: 5,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -0.46,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 0,
            低倍率病例占比是否标红: false,
            出院科室名称: '神经内科',
            平均住院天数: 11,
            '平均超支结余(元)': -717.39,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 6237.68,
            次均费用是否标红: true,
            病例数: 4,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -0.29,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 0,
            低倍率病例占比是否标红: false,
            出院科室名称: '消化内科',
            平均住院天数: 10.5,
            '平均超支结余(元)': -191.92,
            平均超支结余是否标红: true,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 5397.38,
            次均费用是否标红: false,
            病例数: 4,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': -0.08,
            超支结余是否标红: true,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
          {
            低倍率病例占比: 100,
            低倍率病例占比是否标红: true,
            出院科室名称: '骨科二',
            平均住院天数: 2,
            '平均超支结余(元)': 44.63,
            平均超支结余是否标红: false,
            '次均材料费(元)': 0,
            '次均药费(元)': 0,
            '次均费用(元)': 2399.09,
            次均费用是否标红: false,
            病例数: 1,
            '耗占比(%)': 0,
            '药占比(%)': 0,
            '超支结余(万元)': 0,
            超支结余是否标红: false,
            高倍率病例占比: 0,
            高倍率病例占比是否标红: false,
          },
        ],
        desc: 'ES23病组分布在8个科室，列表取病例数前8,其中亏损科室病例数<span style="color:#ff1310">373</span>例，病组总病例数中所占比例为<span style="color:#ff1310">99.73%</span>，亏损金额<span style="color:#ff1310">-9.75</span>万元，结余科室病例数<span style="color:#ff1310">1</span>例，病组总病例数中所占比例为<span style="color:#ff1310">0.27%</span>结余金额<span style="color:#ff1310">0.0</span>万元。<br/>科室老年医学科，平均住院天数高于病组平均住院天数；科室老年病科二，平均住院天数高于病组平均住院天数；科室神经内科，平均住院天数高于病组平均住院天数；科室消化内科，平均住院天数高于病组平均住院天数',
        title: '2024年1-12月',
        '地区均费(元)': 6728.18,
        病组平均住院天数: 10.18,
      }),
    },
    columns: {
      type: Object,
      default: () => ({
        columns1: [
          {
            label: 'DRG分组',
            prop: 'DRG分组',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.5,
            pptContentFontSize: 8,
          },
          {
            label: 'DRG分组名称',
            prop: 'DRG分组名称',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: 'RW',
            prop: 'RW',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 4,
            pptContentFontSize: 8,
          },
          {
            label: '地区均费(元)',
            prop: '地区均费(元)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 7,
            pptContentFontSize: 8,
          },
          {
            label: '病组平均住院天数',
            prop: '病组平均住院天数',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
        ],
        columns2: [
          {
            label: '低倍率病例占比',
            prop: '低倍率病例占比',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: '出院科室名称',
            prop: '出院科室名称',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: '平均住院天数',
            prop: '平均住院天数',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: '平均超支结余(元)',
            prop: '平均超支结余(元)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 8,
            pptContentFontSize: 8,
          },
          {
            label: '次均材料费(元)',
            prop: '次均材料费(元)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: '次均药费(元)',
            prop: '次均药费(元)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: '次均费用(元)',
            prop: '次均费用(元)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 8,
            pptContentFontSize: 8,
          },
          {
            label: '病例数',
            prop: '病例数',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.38,
            pptContentFontSize: 8,
          },
          {
            label: '耗占比(%)',
            prop: '耗占比(%)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 4.82,
            pptContentFontSize: 8,
          },
          {
            label: '药占比(%)',
            prop: '药占比(%)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 4.82,
            pptContentFontSize: 8,
          },
          {
            label: '超支结余(万元)',
            prop: '超支结余(万元)',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
          {
            label: '高倍率病例占比',
            prop: '高倍率病例占比',
            headerFontSize: 14,
            contentFontSize: 14,
            widthPercent: 5.88,
            pptContentFontSize: 8,
          },
        ],
      }),
    },
  },
  data() {
    return {
      // 红色标记字段映射
      redFlagMapping: {
        低倍率病例占比: '低倍率病例占比是否标红',
        '平均超支结余(元)': '平均超支结余是否标红',
        '次均费用(元)': '次均费用是否标红',
        '超支结余(万元)': '超支结余是否标红',
        高倍率病例占比: '高倍率病例占比是否标红',
      },
    };
  },
  methods: {
    // 获取单元格样式类
    getCellClass(row, prop) {
      const redFlagProp = this.redFlagMapping[prop];
      if (redFlagProp && row[redFlagProp]) {
        return 'red-text';
      }
      return '';
    },
    // 格式化单元格值
    formatCellValue(value) {
      if (typeof value === 'number') {
        return value.toLocaleString();
      }
      return value;
    },
    // 导出PPT
    exportToPPT(pptx, slide) {
      let tabOpts = {
        x: this.pptOptions.x,
        y: this.pptOptions.y,
        h: this.pptOptions.h,
        w: '95%',
        colW: this.pptOptions.table.colW,
        rowH: this.pptOptions.table.rowH,
        border: {
          pt: 1,
          color: this.pptOptions.table.borderStyle.color,
        },
        align: this.pptOptions.table.align,
        valign: this.pptOptions.table.valign,
        // 自动分页配置
        autoPage: this.pptOptions.table.autoPage,
        autoPageRepeatHeader: this.pptOptions.table.autoPageRepeatHeader,
        autoPageHeaderRows: this.pptOptions.table.autoPageHeaderRows,
      };

      // 动态生成表格数据
      let arrTabRows = [];

      // 表头行
      let headerRow = [];
      // 基本信息表头
      this.columns.columns1.forEach(col => {
        headerRow.push({
          text: col.label,
          options: {
            fill: { color: this.headerBgColor ? this.headerBgColor.replace('#', '') : '4874cb' },
            color: this.pptOptions.table.title.color,
            fontSize: col.pptContentFontSize || this.pptOptions.table.title.fontSize,
            valign: this.pptOptions.table.valign,
            align: this.pptOptions.table.align,
            bold: this.pptOptions.table.content.bold,
          },
        });
      });
      // 详细数据表头
      this.columns.columns2.forEach(col => {
        headerRow.push({
          text: col.label,
          options: {
            fill: { color: this.headerBgColor ? this.headerBgColor.replace('#', '') : '4874cb' },
            color: this.pptOptions.table.title.color,
            fontSize: col.pptContentFontSize || this.pptOptions.table.title.fontSize,
            valign: this.pptOptions.table.valign,
            align: this.pptOptions.table.align,
            bold: this.pptOptions.table.content.bold,
          },
        });
      });
      arrTabRows.push(headerRow);

      // 数据行
      this.tableData.data.forEach((row, index) => {
        let dataRow = [];
        // 判断是否为偶数行（从0开始计数，所以偶数行是0,2,4...）
        const isEvenRow = index % 2 === 0;
        const rowFillColor = isEvenRow ? 'f5f5f5' : 'ffffff';

        // 基本信息列 - 只在第一行显示，使用rowspan
        if (index === 0) {
          this.columns.columns1.forEach(col => {
            dataRow.push({
              text: String(this.tableData[col.prop] || ''),
              options: {
                rowspan: this.tableData.data.length,
                fill: { color: 'ffffff' },
                color: this.pptOptions.table.content.color,
                fontSize: col.pptContentFontSize || this.pptOptions.table.content.fontSize,
                valign: this.pptOptions.table.valign,
                align: this.pptOptions.table.align,
                bold: this.pptOptions.table.content.bold,
              },
            });
          });
        }

        // 详细数据列
        this.columns.columns2.forEach(col => {
          let value = this.formatCellValue(row[col.prop]);
          // 检查是否需要标红显示
          const shouldHighlight = this.redFlagMapping[col.prop];
          let cellOptions = {
            fontSize: col.pptContentFontSize || this.pptOptions.table.content.fontSize,
            color: shouldHighlight ? 'ee6666' : this.pptOptions.table.content.color,
            fill: { color: rowFillColor },
            valign: this.pptOptions.table.valign,
            align: this.pptOptions.table.align,
            bold: this.pptOptions.table.content.bold,
          };

          dataRow.push({
            text: String(value),
            options: cellOptions,
          });
        });

        arrTabRows.push(dataRow);
      });

      slide.addTable(arrTabRows, tabOpts);
    },
  },
};
</script>

<style scoped>
.data-table-vertical {
  height: 100%;
}

.table-title {
  font-size: 18px;
  font-weight: bold;
  color: #333;
  flex: 1;
  text-align: center;
}

.export-btn {
  background: #4874cb;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s ease;
}

.export-btn:hover {
  background: #3a5fb0;
}

.export-btn:active {
  background: #2d4a8a;
}

.merged-table {
  height: 100%;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  height: 100%;
}

.data-table th,
.data-table td {
  border: 1px solid #000;
  padding: 8px 12px;
  text-align: center;
}

/* 基本信息表头样式 */
.basic-info-header {
  background-color: v-bind(headerBgColor);
  color: white;
  font-weight: bold;
  text-align: center;
  vertical-align: middle;
}

/* 详细数据表头样式 */
.detail-data-header {
  background-color: v-bind(headerBgColor);
  color: white;
  font-weight: bold;
  text-align: center;
  vertical-align: middle;
}

/* 基本信息单元格样式 */
.basic-info-cell {
  font-weight: bold;
  text-align: center;
  vertical-align: middle;
  border-right: 2px solid v-bind(headerBgColor);
}

/* 详细数据单元格样式 */
.detail-data-cell {
  background-color: #fff;
  text-align: center;
  vertical-align: middle;
  font-weight: bold;
}

/* 斑马纹效果 */
.data-table tbody tr:nth-child(even) .detail-data-cell {
  background-color: #f5f5f5;
}

/* 红色标记文字 */
.detail-data-cell.red-text {
  color: #ff1310 !important;
  font-weight: bold;
}

.red-text {
  color: #ff1310 !important;
  font-weight: bold;
}

/* 表格滚动条样式 */
.merged-table::-webkit-scrollbar {
  height: 8px;
}

.merged-table::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.merged-table::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.merged-table::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style>
